package zhu.yu.OOP_abstract_class.多态;
/*
Polymorphism:多态性

代码当中体现多态性，其实就是一句话，父类引用指向子类对象
格式：
父类名称 对象名 = new 子类名称();
或者：
接口名称 对象名 = new 实现类名称();
 */

/*
访问成员变量的两种方式：
1. 直接通过对象名称访问成员变量，看等号左边是谁，优先用谁，没有则向上找
2. 间接通过成员方法访问成员变量，看该方法属于谁，优先用谁，没有则向上找

注意：
成员变量不能重写

多态总结：
如果父类定义方法，直接通过 对象名.方法名(); 访问
如果父类定义的方法被子类重写，直接通过 对象名.方法名(); 访问，并且访问的是子类的方法
如果子类有方法，不是重写父类的方法 不能访问
 */

/*
向上转型一定是安全的，没有问题的，正确的，但是也有弊端
对象一旦向上转型为父类，那么就无法调用子类原本独有的方法

如果就是想用子类独有的方法?
解决方案：
用对象的向下转型【还原】
 */
public class DemoPolymorphism {

    public static void main(String[] args) {

        // 使用多态的写法
        // 左侧父类的引用，指向了右侧子类的对象
        Fu obj = new Zi();
        obj.method(); // 子类方法
        obj.methodFu(); // 这是个父类独有方法

        // 使用多态的写法, 父类引用指向子类对象
        Fu obj2 = new Zi();

        // 等号左边是父类，所有先访问父类, 成员变量不能重写
        System.out.println(obj2.num);  // 10
//        System.out.println(obj2.number);  // 访问不了子类的成员变量

        // 子类重写就是子类方法
        // 子类没有重写就是父类方法
        obj2.getNum(); // 11


        // 对象的向上转型
        Fu fu = new Zi();
        // 调用子类方法
//        fu.methodZi();  错误写法

        // 向下转型
        Zi zi = (Zi) fu;
        // 调用子类方法
        zi.methodZi();  // 子类独有方法

        // 错误向下转型案例
        Zi2 zi2 = (Zi2) fu; // 错误写法编译不会报错，但是运行会报异常;   java.lang.ClassCastException  类转换异常
        // Exception in thread "main" java.lang.ClassCastException: zhu.yu.OOP_abstract_class.多态.Zi cannot be cast to zhu.yu.OOP_abstract_class.多态.Zi2
        //	at zhu.yu.OOP_abstract_class.多态.DemoPolymorphism.main(DemoPolymorphism.java:67)
    }
}
